﻿// ----------------------------------------------------------------------------------
// <copyright file="PluginTypeProcessor.cs" company="Christopher Hines">
// Copyright (c) 2012 All Right Reserved
// </copyright>
// <author>Chris Hines</author>
// <date>2012-02-16</date>
// <summary>
//     Processor for plugin types
// </summary>
// ----------------------------------------------------------------------------------

namespace Copperfield
{
    using System;

    /// <summary>
    /// Processor for plugin types
    /// </summary>
    internal class PluginTypeProcessor : IContextProcessor
    {
        /// <summary>
        /// Gets the plugin configuration delegate
        /// </summary>
        /// <value>
        /// The plugin configuration delegate
        /// </value>
        private readonly Action<Type, Type, Func<Type, Type, object>> pluginConfigurationDelegate;

        /// <summary>
        /// Initializes a new instance of the PluginTypeProcessor class
        /// </summary>
        /// <param name="pluginConfigurationAgent">The plugin configuration agent</param>
        internal PluginTypeProcessor(Action<Type, Type, Func<Type, Type, object>> pluginConfigurationAgent)
        {
            this.pluginConfigurationDelegate = pluginConfigurationAgent;
        }

        /// <summary>
        /// Processes a type accordingly if it is a type of Plugin Type
        /// </summary>
        /// <param name="type">The type that will be processed</param>
        public void Process(Type type)
        {
            ContextPluginAttribute attribute;
            {
                if (!TypeUtility.TryGetAttribute(type, out attribute))
                {
                    return;
                }
            }

            var pluginType = attribute.PluginType ?? type;
            var contextType = attribute.ContextType;

            this.pluginConfigurationDelegate(pluginType, contextType, ContextContainer.GetInstance);

            var contextualCollectionType = TypeUtility.CreateGenericType(typeof(IContextualCollection<>), pluginType);
            this.pluginConfigurationDelegate(contextualCollectionType, contextType, ContextContainer.GetInstances);

            CopperfieldConfiguration
                .ContextResolutionConfigurationExpressions()
                .ForEach(x => x.Process(attribute));
        }
    }
}
